/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package matematicadiscretaxml;

import java.util.ArrayList;
/**
 *
 * @author diego
 */
public class AnalizadorLexico {

    private String cadenaSQL = "";
    private ArrayList lista_tokens = new ArrayList();
    private ArrayList lista_errores_lex = new ArrayList();

    public AnalizadorLexico(){}

    public AnalizadorLexico(String _cadenaSQL)
    {
        cadenaSQL = _cadenaSQL;
    }

//*********CLASIFICACION DE LEXEMAS
//PALABRAS RESERVADAS   1
//SIMBOLOS              2
//OPERADORES            3
//IDENTIFICADORES       4 (TABLAS Y CAMPOS)
//CONSTANTE CADENA      5
//CONSTANTE NUMERO      6
    
    /*
     * ESTA FUNCION DIVIDE LA CADENA EN TOKENS Y LOS CLASIFICA SEGUN TIPO DE LEXEMA,
     * VALIDA QUE LAS CONSTANTES CADENAS ESTEN BIEN INGRESADAS
     */
    public void generarTokens()
    {

        String cadena_aux = "";
        String cadena_concat = "";

        cadena_aux = this.getCadenaSQL();

        XML xml_pal_reserv = new XML("archivos_usados/analisis_lexico/diccionario/palabras_reservadas.xml");
        XML xml_simbolos = new XML("archivos_usados/analisis_lexico/diccionario/simbolos.xml");
        XML xml_operadores = new XML("archivos_usados/analisis_lexico/diccionario/operadores.xml");

        ArrayList arreglo_pal_reserv = xml_pal_reserv.leerXMLDiccionario();
        ArrayList arreglo_simbolos = xml_simbolos.leerXMLDiccionario();
        ArrayList arreglo_operadores = xml_operadores.leerXMLDiccionario();

        Lexema lex;
        Error error;
        boolean bandera_error = false;

        int bandera_constante_cadena = 0;
        int tipo_lexema = 0;
        
        for (int i = 0 ; i < cadena_aux.length(); i++)
        {
            if(cadena_aux.charAt(i)== '{' || cadena_aux.charAt(i)== '}')
            {
//                System.out.println("ACA ESTA LA E DEL MAL");
            }
            if((int)(cadena_aux.charAt(i)) == 39)
            {
                bandera_constante_cadena++;
            }
            
            if( bandera_constante_cadena != 0 )
            {
                
                if(bandera_constante_cadena == 1)
                {
                    if(tipo_lexema == 2 || tipo_lexema == 3)
                    {
                        lex = new Lexema(tipo_lexema , cadena_concat);
                        lista_tokens.add(lex);
                        cadena_concat="";
                    }
                    tipo_lexema = 5;
                    cadena_concat = cadena_concat+cadena_aux.charAt(i);
                }
                else if (bandera_constante_cadena == 2)
                {
                    cadena_concat = cadena_concat+cadena_aux.charAt(i);
                    lex = new Lexema(tipo_lexema , cadena_concat);
                    lista_tokens.add(lex);
                    cadena_concat="";
                    tipo_lexema = 0;
                    bandera_constante_cadena = 0;
                }

            }
            else 
            {
                if(buscarLista(arreglo_pal_reserv, cadena_concat+cadena_aux.charAt(i) ))//LA CADENA CONCATENADA ES PALABRA RESERVADA
                {
                    cadena_concat = cadena_concat+cadena_aux.charAt(i);
                    tipo_lexema  = 1;
                }
                else if(buscarLista(arreglo_simbolos, cadena_concat+cadena_aux.charAt(i) ))//LA CADENA CONCATENADA ES UN SIMBOLO
                {
                    cadena_concat = cadena_concat+cadena_aux.charAt(i);
                    tipo_lexema  = 2;
                }
                else if(buscarLista(arreglo_operadores, cadena_concat+cadena_aux.charAt(i) ))//LA CADENA CONCATENADA ES UN OPERADOR
                {
                    cadena_concat = cadena_concat+cadena_aux.charAt(i);
                    tipo_lexema  = 3;
                }
                else
                {
                    if(tipo_lexema != 0 )
                    {
                        if( esCaracterTerminal(cadena_aux.charAt(i)))
                        {
                            lex = new Lexema(tipo_lexema , cadena_concat);
//                            System.out.println("AJAAAAAAAAAAAA: "+cadena_concat);
                            lista_tokens.add(lex);
                            if(buscarLista(arreglo_simbolos, String.valueOf(cadena_aux.charAt(i)) ) )
                            {
                                cadena_concat=String.valueOf(cadena_aux.charAt(i)) ;
                                tipo_lexema = 2;
                                lex = new Lexema(tipo_lexema , cadena_concat);
                                lista_tokens.add(lex);
                                cadena_concat="";
                                tipo_lexema = 0;
                            }
                            else
                            {
                                cadena_concat="";
                                tipo_lexema = 0;
                            }
                            
                        }
                        /*
                         * ACA DEBE MARCAR ERROR
                         */
                        else if(tipo_lexema == 1 && !esCaracterTerminal(cadena_aux.charAt(i)))
                        {
                            tipo_lexema = 0;
                            cadena_concat=cadena_concat+cadena_aux.charAt(i);
                        }
                        else if (tipo_lexema == 2 || tipo_lexema == 3 )
                        {
                            lex = new Lexema(tipo_lexema , cadena_concat);
                            lista_tokens.add(lex);
                            cadena_concat=""+cadena_aux.charAt(i);
                            tipo_lexema = 0;
                        }
//                        else
//                        {
//                            if( buscarLista(arreglo_simbolos, String.valueOf(cadena_aux.charAt(i)) ) )
//                            {
//                                lex = new Lexema(tipo_lexema , cadena_concat);
//                                lista_tokens.add(lex);
//                                cadena_concat=String.valueOf(cadena_aux.charAt(i));
//                                tipo_lexema = 2;
//                                lex = new Lexema(tipo_lexema , cadena_concat);
//                                lista_tokens.add(lex);
//                                cadena_concat="";
//                                tipo_lexema = 0;
//                            }
//                        }

                    }
                    else//LA CADENA CONCATENADA NO ES UNA PALABRA RESERVADA U OPERADOR O SIMBOLO
                    {
                        /*
                         * LA CADENA CONCATENADA NO ES UNA PALABRA RESERVADA U OPERADOR O SIMBOLO
                         * Y EL CARACTER ACTUAL ES SIMBOLO TERMINAL
                         */
                        if(tipo_lexema == 0 &&  esCaracterTerminal(cadena_aux.charAt(i)) && cadena_concat.trim().length() != 0)
                        {
                            if( esNumero(cadena_concat) )//DETERMINA SI LA CADENA INGRESADA ES UN IDENTIFICADOR O ES UN NUMERO
                            {
                                tipo_lexema = 6;
                            }
                            else
                            {
                                tipo_lexema = 4;
                            }

                            lex = new Lexema(tipo_lexema , cadena_concat);
                            lista_tokens.add(lex);
                            if(buscarLista(arreglo_operadores, ""+cadena_aux.charAt(i)) || buscarLista(arreglo_simbolos, ""+cadena_aux.charAt(i)) )
                            {

                                if( buscarLista(arreglo_operadores, ""+cadena_aux.charAt(i)) )
                                {
                                    tipo_lexema = 3;
                                }
                                else
                                {
                                    tipo_lexema = 2;
                                }
                                cadena_concat=""+cadena_aux.charAt(i);
                                lex = new Lexema(tipo_lexema , cadena_concat);
                                lista_tokens.add(lex);
                            }
                            cadena_concat="";
                            tipo_lexema = 0;
                        }
                        /*
                         * LA CADENA CONCATENADA NO ES UNA PALABRA RESERVADA U OPERADOR O SIMBOLO
                         * Y EL CARACTER ACTUAL NO ES SIMBOLO TERMINAL
                         */
                        else if(tipo_lexema == 0 &&  !esCaracterTerminal(cadena_aux.charAt(i)))
                        {
                            cadena_concat = cadena_concat + cadena_aux.charAt(i);
                            if(i == cadena_aux.length() -1)
                            {
//                                System.out.println("ENTRA AQUI YEAH");
                                if( esNumero(cadena_concat) )//DETERMINA SI LA CADENA INGRESADA ES UN IDENTIFICADOR O ES UN NUMERO
                                {
                                    tipo_lexema = 6;
                                }
                                else
                                {
                                    tipo_lexema = 4;
                                }
                            }
                            else
                            {
                                tipo_lexema = 0;
                            }
                        }
                    }
                }
            }
        }

        if(bandera_constante_cadena == 1)//VALIDA SI SE CERRO BIEN UNA CADENA
        {
            error = new Error("INGRESO CONSTANTE CADENA", "LA CONSTANTE CADENA DEBE ESTAR ENCERRADA POR COMILLAS SIMPLES (ejemplo: 'constante_cadena')");
            getLista_errores_lex().add(error);
            bandera_error = true;
        }

        if(cadena_concat.trim().length()!= 0)
        {
            lex = new Lexema(tipo_lexema , cadena_concat);
            lista_tokens.add(lex);
            cadena_concat="";
        }
        
    }

    public boolean esNumero(String cadena)
    {
        boolean bandera_respuesta = false;
        
        try
        {
            Float.parseFloat(cadena);
            bandera_respuesta = true;
        }
        catch (NumberFormatException nfe)
        {
            bandera_respuesta = false;
        }

        return bandera_respuesta;
    }

    public boolean esCaracterTerminal(char caracter)
    {
        boolean bandera_encontrado = false;
        if(caracter== ' ' || caracter== '\n' || caracter== '\t' || caracter== ',' || 
                caracter== '=' || caracter== ';' || caracter== '>' || caracter== '<'
                || caracter== '(' || caracter== ')'|| caracter== '{' || caracter== '}')
        {
            bandera_encontrado = true;
        }
        return bandera_encontrado;
    }

    /*
     * ESTO NO SE UTILIZA PUESTO QUE NO SE IMPLEMENTO MENOR, MAYOR, MENOR IGUAL NI MAYOR IGUAL
     */
    public boolean esCaracterTerminal(String cadena)
    {
        boolean bandera_encontrado = false;
        if( cadena.equals(">=") || cadena.equals("<=") || cadena.equals("<>") )
        {
            bandera_encontrado = true;
        }
        return bandera_encontrado;
    }


    public boolean buscarLista(ArrayList lista, String cadena)
    {
        boolean bandera_encontrado = false;
        for(int i = 0; i< lista.size(); i++)
        {
            if(lista.get(i).equals(cadena.toLowerCase()))
            {
                bandera_encontrado = true;
            }
        }
        return bandera_encontrado;
    }

    
    public boolean buscarDisccionarioArreglo(ArrayList arreglo, String cadena)
    {
        boolean encontrado = false;

        for (int i = 0; i < arreglo.size(); i++)
        {
            if (cadena.equals(arreglo.get(i).toString()))
            {
                encontrado = true;
            }
        }

        return encontrado;
    }

    /**
     * @return the cadenaSQL
     */
    public String getCadenaSQL() {
        return cadenaSQL;
    }

    /**
     * @param cadenaSQL the cadenaSQL to set
     */
    public void setCadenaSQL(String cadenaSQL) {
        this.cadenaSQL = cadenaSQL;
    }

    /**
     * @return the lista_tokens
     */
    public ArrayList getLista_tokens() {
        return lista_tokens;
    }

    /**
     * @param lista_tokens the lista_tokens to set
     */
    public void setLista_tokens(ArrayList lista_tokens) {
        this.lista_tokens = lista_tokens;
    }

    /**
     * @return the lista_errores_lex
     */
    public ArrayList getLista_errores_lex() {
        return lista_errores_lex;
    }

    /**
     * @param lista_errores_lex the lista_errores_lex to set
     */
    public void setLista_errores_lex(ArrayList lista_errores_lex) {
        this.lista_errores_lex = lista_errores_lex;
    }

}
